import mapboxgl, { LngLatLike } from "mapbox-gl"
import * as THREE from "three"
var uniforms = {
    iTime: {
      type: 'f',
      value: 1.0
    }
  }
  function findOrigin(pointArr) {
    let min = pointArr.reduce((min, item, index) => {
      if (item.lt < min) {
        min = item.lt
      }
      return min
    }, pointArr[0].lt)
    // 多个维度相同的情况
    let minItems = pointArr
      .filter(i => i.lt == min)
      .sort((a, b) => a.ln - b.ln)[0]
    return minItems
  }
  // const ali = [
  //   { ln: 120.18669699897104, lt: 30.195734047408006 },
  //   { ln: 120.18481867562849, lt: 30.19657615976094 },
  //   { ln: 120.18359146384691, lt: 30.19639727074671 },
  //   { ln: 120.1843631355107, lt: 30.190991367324166 },
  //   { ln: 120.18775940533932, lt: 30.1911974675611 }
  // ]
  const ali = [
    [
      115.86003054256423,
      28.677277537693342
    ],
    [
      115.85919544410348,
      28.67500514441653
    ],
    [
      115.8592075327586,
      28.673609913363194
    ],
    [
      115.8595587871257,
      28.673005966626036
    ],
    [
      115.85937177978349,
      28.670606868780908
    ],
    [
      115.85954507808896,
      28.67009665253137
    ],
    [
      115.85881532886333,
      28.669188424389674
    ],
    [
      115.85892114783417,
      28.668539634861887
    ],
    [
      115.85975355252987,
      28.668429299731628
    ],
    [
      115.85995983732698,
      28.66841338240576
    ],
    [
      115.86056649451223,
      28.668393973766058
    ],
    [
      115.86193105792256,
      28.66893645532069
    ],
    [
      115.8626893206199,
      28.669773085866424
    ],
    [
      115.86276018365675,
      28.67049629060756
    ],
    [
      115.86245672280046,
      28.67107145405521
    ],
    [
      115.86262862623693,
      28.672267193343814
    ],
    [
      115.86242050909976,
      28.67294205649307
    ],
    [
      115.86239117293246,
      28.673912187766334
    ],
    [
      115.86150036893008,
      28.674607636909585
    ],
    [
      115.86135701569629,
      28.677180352193886
    ],
    [
      115.8609868988546,
      28.677378776626
    ],
    [
      115.86003054256423,
      28.677277537693342
    ]
  ].map(item=>{
    return   { ln: item[0], lt: item[1] }
  })
  /*const ali = [
    { ln: 121.46094899678036, lt: 31.271899107707668},
    { ln: 121.46153824253952, lt: 31.27222640595184 },
    { ln: 121.46102600443686, lt: 31.27179697580307},
    { ln: 121.461617504772, lt: 31.272125516275565}
  ]*/
  //121.46094899678036, 31.271899107707668
  //121.46153824253952, 31.27222640595184
  //121.46102600443686, 31.27179697580307
  //121.461617504772, 31.272125516275565
  /*const ali=[[121.46028954799999,31.271502721300124],
    [121.460289547,31.271521054100106],
    [121.45994521099999,31.27133686590014],
    [121.46002054600012,31.271245389400008],
    [121.460289558,31.271383557900094],
    [121.46028954799999,31.271502721300124]]*/
  const { ln: minln, lt: minlt } = findOrigin(ali)
  const relativePosition = ali.map(item => {
    return {
      ln: (item.ln - minln) * 10000,
      lt: (item.lt - minlt) * 10000
    }
  })

  const center = ali
    .reduce(
      (a, b) => {
        a[0] = a[0] + b.ln
        a[1] = a[1] + b.lt
        return a
      },
      [0, 0]
    )
    .map(i => i / ali.length)
//   mapboxgl.accessToken =
//     'pk.eyJ1IjoibXlzb21lIiwiYSI6ImNrMzhkeGM3cTAxM2czZHFldmxkOWQ3N2gifQ.LHODCWg-jAbqBZmOOHtnqQ'
//   var map = (window.map = new mapboxgl.Map({
//     container: 'map',
//     style: 'mapbox://styles/mysome/ck47tr3xs01n61cmdku8zmw9a',
//     zoom: 18,
//     center: center,
//     pitch: 60,
//     antialias: true // create the gl context with MSAA antialiasing, so custom layers are antialiased
//   }))

  // parameters to ensure the model is georeferenced correctly on the map
  var modelOrigin:LngLatLike = [minln, minlt] // 最大x 最小y
  // var modelOrigin = [120.18775940533932, 30.1911974675611]
  var modelAltitude = 0
  var modelRotate = [Math.PI / 2, 0, 0]

  var modelAsMercatorCoordinate = mapboxgl.MercatorCoordinate.fromLngLat(
    modelOrigin,
    modelAltitude
  )

  // transformation parameters to position, rotate and scale the 3D model onto the map
  var modelTransform = {
    translateX: modelAsMercatorCoordinate.x,
    translateY: modelAsMercatorCoordinate.y,
    translateZ: modelAsMercatorCoordinate.z,
    rotateX: modelRotate[0],
    rotateY: modelRotate[1],
    rotateZ: modelRotate[2],
    /* Since our 3D model is in real world meters, a scale transform needs to be
     * applied since the CustomLayerInterface expects units in MercatorCoordinates.
     */
    scale: modelAsMercatorCoordinate.meterInMercatorCoordinateUnits()
  }

//   var THREE = window.THREE

  // configuration of the custom layer for a 3D model per the CustomLayerInterface
  export const customLayer = {
    id: '3d-model',
    type: 'custom',
    renderingMode: '3d',
    onAdd: function(map, gl) {
      this.camera = new THREE.Camera()
      this.scene = new THREE.Scene()
      // var axesHelper = new THREE.AxesHelper(800)
      // this.scene.add(axesHelper)

      // create two three.js lights to illuminate the model
      var directionalLight = new THREE.DirectionalLight(0xffffff)
      directionalLight.position.set(0, -70, 100).normalize()
      this.scene.add(directionalLight)

      var directionalLight2 = new THREE.DirectionalLight(0xffffff)
      directionalLight2.position.set(0, 70, 100).normalize()
      this.scene.add(directionalLight2)

      this.map = map

      getShapN(this.scene)

      // use the Mapbox GL JS map canvas for three.js
      this.renderer = new THREE.WebGLRenderer({
        canvas: map.getCanvas(),
        context: gl,
        antialias: true
      })

      this.renderer.autoClear = false
    },
    render: function(gl, matrix) {
      var rotationX = new THREE.Matrix4().makeRotationAxis(
        new THREE.Vector3(1, 0, 0),
        modelTransform.rotateX
      )
      var rotationY = new THREE.Matrix4().makeRotationAxis(
        new THREE.Vector3(0, 1, 0),
        modelTransform.rotateY
      )
      var rotationZ = new THREE.Matrix4().makeRotationAxis(
        new THREE.Vector3(0, 0, 1),
        modelTransform.rotateZ
      )

      var m = new THREE.Matrix4().fromArray(matrix)
      var l = new THREE.Matrix4()
        .makeTranslation(
          modelTransform.translateX,
          modelTransform.translateY,
          modelTransform.translateZ
        )
        .scale(
          new THREE.Vector3(
            modelTransform.scale,
            -modelTransform.scale,
            modelTransform.scale
          )
        )
        .multiply(rotationX)
        .multiply(rotationY)
        .multiply(rotationZ)

      this.camera.projectionMatrix = m.multiply(l)
      this.renderer.state.reset()
      uniforms.iTime.value += 0.05
      this.renderer.render(this.scene, this.camera)
      this.map.triggerRepaint()
    }
  }

//   map.on('style.load', function() {
//     map.addLayer(customLayer, 'waterway-label')
//     map.on('click', function (e) {
//       var coordinates = e.lngLat;
//       console.log(coordinates,'111111111')

//       alert(coordinates);
//     });
//   })


  function getShapN(scene) {
    // var material = new THREE.MeshBasicMaterial({
    //   color: 0xffff00,
    //   side: THREE.DoubleSide
    // })
    var material = new THREE.ShaderMaterial({
      uniforms: uniforms,
      transparent: true,
      side: 2,
      vertexShader: document.getElementById('vertexShader').textContent,
      fragmentShader: document.getElementById('fragmentShader').textContent
    })
    let wareGroup = new THREE.Group()
    let height = 10
    // 形状的坐标数据
    const shapArr = relativePosition
    for (let index = 0; index < shapArr.length; index++) {
      const item = shapArr[index]
      const nextItem =
        index + 1 == shapArr.length ? shapArr[0] : shapArr[index + 1]
      // 计算出两点的距离
      const length = getTwoPointLength(item, nextItem)
      // 根据形状构建mesh
      let mesh = new THREE.Mesh(
        new THREE.PlaneGeometry(length, height),
        material
      )
      // 获取到两点之间，中心点的坐标
      const pos = getMiddlePos(item, nextItem)
      // 计算出两点之间的旋转角度
      const roate = Math.asin((nextItem.ln - pos.ln) / (length / 2))
      console.log(item, nextItem, pos)
      // 设置mesh的坐标
      mesh.position.x = pos.ln
      mesh.position.z = pos.lt
      mesh.position.y = height / 2
      if (nextItem.lt - pos.lt > 0) {
        mesh.rotation.y = Math.PI / 2 + roate
      } else {
        mesh.rotation.y = Math.PI / 2 - roate
      }
      wareGroup.add(mesh)
    }
    let beishu = 5
    wareGroup.scale.x = 10
    wareGroup.scale.z = 11
    wareGroup.scale.y = beishu
    // 镜像反转
    wareGroup.rotation.x = Math.PI * -1
    wareGroup.position.y = beishu * height
    scene.add(wareGroup)
  }

  function getTwoPointLength(a, b) {
    // 勾股定理
    let width = Math.abs(a.ln - b.ln)
    let height = Math.abs(a.lt - b.lt)
    return Math.hypot(width, height)
  }
  function getMiddlePos(a, b) {
    return {
      ln: (a.ln + b.ln) / 2,
      lt: (a.lt + b.lt) / 2
    }
  }